#include<iostream>
#include<stdio.h>
#include<cstdlib>
#include<sys/time.h>
#include<omp.h>
#include "GRMAT.h"
#define VERTICES 64
using namespace std;

int modulo(int a, int b)
{
  if(a<0)
    {
      int z=a;
      while(z<0)
	{
	  z+=b;
	}
      return z;
    }else
    {
      return a%b;
    }
};

void Fill_Graph(Graphm & G, int n)
{
  int v=n*n;
  for(int i=0; i<v;i++)
    {
      int k=i%n;
      int j=i/n;
      G.setEdge(i,n*j+modulo(k-1,n),1);
      G.setEdge(i,n*j+modulo(k+1,n),1);
      G.setEdge(i,n*modulo(j-1,n)+k,1);
      G.setEdge(i,n*modulo(j-1,n)+modulo(k+1,n),1);
      G.setEdge(i,n*modulo(j-1,n)+modulo(k-1,n),1);
      G.setEdge(i,n*modulo(j+1,n)+k,1);
      G.setEdge(i,n*modulo(j+1,n)+modulo(k+1,n),1);
      G.setEdge(i,n*modulo(j+1,n)+modulo(k-1,n),1);
    }
};

void DFS(Graph* G, int v)
{
  G->setMark(v, VISITED);
  cout<<"vertex: "<<v<<endl;
#pragma omp parallel for
  for (int w=G->first(v); w<G->n();w = G->next(v,w))
    if (G->getMark(w) == UNVISITED) 
      DFS(G, w);
};

int main()
{
  int start=0;
  Graphm G(VERTICES);
  for(int i=0;i<VERTICES;i++)
    {
      for(int j=0;j<VERTICES;j++)
	{
	  G.setEdge(i,j,0);
	}
    }
  Fill_Graph(&G,8);
  /*
  G.setEdge(0,2,1);
  G.setEdge(0,4,1);
  G.setEdge(1,2,1);
  G.setEdge(1,5,1);
  G.setEdge(2,0,1);
  G.setEdge(2,1,1);
  G.setEdge(2,3,1);
  G.setEdge(2,5,1);
  G.setEdge(3,2,1);
  G.setEdge(3,5,1);
  G.setEdge(4,0,1);
  G.setEdge(4,5,1);
  G.setEdge(5,1,1);
  G.setEdge(5,2,1);
  G.setEdge(5,3,1);
  G.setEdge(5,4,1);
  */
  timeval tim;
  gettimeofday(&tim, NULL);
  double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
  //Algorithm
  DFS(&G,start);
  //End of Algorithm
  gettimeofday(&tim, NULL);
  double t2=tim.tv_sec+(tim.tv_usec/1000000.0);
  printf("%.6lf seconds elapsed\n", t2-t1);
  return 0;
}
